/**
 * Generali Solutions d'assurances - Tous droits rï¿½servï¿½s &copy; 2007 - 2010
 */
package fr.generali.accueilclient.ggs.consultationreglements.services.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.Closure;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Transformer;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

import fr.generali.accueilclient.ggs.consultationreglement.builder.DTOCompteClientBuilder;
import fr.generali.accueilclient.ggs.consultationreglement.om.IConsultationDerniersReglements;
import fr.generali.accueilclient.ggs.consultationreglement.om.ICriteresDerniersReglements;
import fr.generali.accueilclient.ggs.consultationreglement.om.IDonneesComplementaires;
import fr.generali.accueilclient.ggs.consultationreglement.om.IInformationsComplementaires;
import fr.generali.accueilclient.ggs.consultationreglement.om.IPersonnePhysique;
import fr.generali.accueilclient.ggs.consultationreglement.om.IQuantity;
import fr.generali.accueilclient.ggs.consultationreglement.om.IReglementSinistre;
import fr.generali.accueilclient.ggs.consultationreglement.om.impl.DTOConsultationDerniersReglements;
import fr.generali.accueilclient.ggs.consultationreglement.om.impl.DTOInformationsComplementaires;
import fr.generali.accueilclient.ggs.consultationreglement.om.impl.DTOPersonnePhysique;
import fr.generali.accueilclient.ggs.consultationreglement.om.impl.DTOQuantity;
import fr.generali.accueilclient.ggs.consultationreglement.om.impl.DTOReglementSinistre;
import fr.generali.accueilclient.utils.constantes.TypeDestinataireReglement;
import fr.generali.accueilclient.utils.spel.mapping.support.MapperBuilder;
import fr.generali.accueilclient.utils.spel.mapping.support.MapperFactory;
import fr.generali.sinistres.prestationssante.ggs.consultationderniersreglements.datatype.MonetaryQuantity;
import fr.generali.sinistres.prestationssante.ggs.consultationderniersreglements.dtocommun.DtoInformationsComplementaires;
import fr.generali.sinistres.prestationssante.ggs.consultationderniersreglements.dtocommun.cla.prestationsinistre.ArrayOfDtoReglementSinistre;
import fr.generali.sinistres.prestationssante.ggs.consultationderniersreglements.dtocommun.cla.prestationsinistre.DtoReglementSinistre;
import fr.generali.sinistres.prestationssante.ggs.consultationderniersreglements.dtocommun.pty.personnes.DtoPersonnePhysique;
import fr.generali.sinistres.prestationssante.ggs.consultationderniersreglements.dtoretour.DtoRetourConsultationDerniersReglements;
import fr.generali.sinistres.prestationssante.ggs.consultationderniersreglements.reglements.DtoConsultationDerniersReglements;

/**
 * @author Holmes Kelly
 */

@Component("consultationDerniersReglementsMapper")
public class ConsultationDerniersReglementsMapper {

    /**
     * Target field
     */
    private static final String TARGET_FIELD_DTOREGLEMENTSINISTRES = "dtoReglementSinistres";

    /**
     * Source field
     */
    private static final String SOURCE_FIELD_DTOREGLEMENTSINISTRE = "dtoReglementSinistre";

    /**
     * identifiant compte technique GGS
     */
    @Value("${ggs.compte.client.identifiant}")
    private String identifiantGGS;

    /**
     * mot de passe compte technique GGS
     */
    @Value("${ggs.compte.client.password}")
    private String motDePasseGGS;

    /**
     * @param criteresDerniersReglements criteres derniers reglements
     */
    public boolean fillCriteresDerniersReglements(ICriteresDerniersReglements criteresDerniersReglements) {

        return fillCompteClientCriteresDerniersReglement(criteresDerniersReglements)
                        && fillDonneesComplementairesCriteresDerniersReglement(criteresDerniersReglements);

    }

    /**
     * @param criteresDerniersReglements criteres consultation reglements
     * @return DtoConsultationDerniersReglements
     */
    public DtoConsultationDerniersReglements mapperConsultationReglementsToCriteresReglements(
                    ICriteresDerniersReglements criteresDerniersReglements) {

        DtoConsultationDerniersReglements dtoConsultationDerniersReglements = null;

        if (criteresDerniersReglements != null) {

            dtoConsultationDerniersReglements = new DtoConsultationDerniersReglements();

            MapperBuilder<ICriteresDerniersReglements, DtoConsultationDerniersReglements> builderConsultationDerniersReglements =
                            MapperFactory.mapperBuilder(ICriteresDerniersReglements.class,
                                            DtoConsultationDerniersReglements.class);

            builderConsultationDerniersReglements.getMapper().map(criteresDerniersReglements,
                            dtoConsultationDerniersReglements);
        }

        return dtoConsultationDerniersReglements;
    }

    /**
     * @param dtoRetourConsultationDerniersReglements
     *            dtoRetourConsultationDerniersReglements
     * @return IConsultationDerniersReglements
     */
    public IConsultationDerniersReglements mapperRetourConsultationDerniersReglement(
                    DtoRetourConsultationDerniersReglements dtoRetourConsultationDerniersReglements) {

        IConsultationDerniersReglements consultationDerniersReglements = null;

        if (dtoRetourConsultationDerniersReglements != null) {

            consultationDerniersReglements = new DTOConsultationDerniersReglements();

            MapperBuilder<DtoRetourConsultationDerniersReglements, IConsultationDerniersReglements> builderRetourConsultationDernierReglement =
                            MapperFactory.mapperBuilder(DtoRetourConsultationDerniersReglements.class,
                                            IConsultationDerniersReglements.class);

            builderRetourConsultationDernierReglement
                            .addConverter(buildMapperInformationComplementaires())
                            .addConverter(buildMapperPersonnePhysique())
                            .addMapping(SOURCE_FIELD_DTOREGLEMENTSINISTRE, TARGET_FIELD_DTOREGLEMENTSINISTRES,
                                            buildMapperListeReglementSinistres()).getMapper()
                            .map(dtoRetourConsultationDerniersReglements, consultationDerniersReglements);
        }

        return consultationDerniersReglements;
    }

    /**
     * @param criteresDerniersReglements criteres derniers reglements
     * @param consultationDerniersReglements consultation derniers reglements
     */
    public boolean fillTypeDestinataireInListeReglementSinistres(
                    ICriteresDerniersReglements criteresDerniersReglements,
                    IConsultationDerniersReglements consultationDerniersReglements) {

        boolean isFillOK = false;

        List<IReglementSinistre> dtoReglementSinistres = consultationDerniersReglements.getDtoReglementSinistres();

        if (CollectionUtils.isNotEmpty(dtoReglementSinistres)) {

            Closure closureTypeDestinataire = fillTypeDestinataireRegleSinistre(criteresDerniersReglements);

            CollectionUtils.forAllDo(dtoReglementSinistres, closureTypeDestinataire);

            isFillOK = true;
        }

        return isFillOK;
    }

    /**
     * @param criteresDerniersReglements criteres derniers reglements
     */
    private boolean fillCompteClientCriteresDerniersReglement(ICriteresDerniersReglements criteresDerniersReglements) {

        DTOCompteClientBuilder dtoCompteClientBuilder =
                        DTOCompteClientBuilder.dTOCompteClient().buildIdentifiant(identifiantGGS)
                                        .buildMotDePasse(motDePasseGGS);

        criteresDerniersReglements.setDtoCompteAppliClient(dtoCompteClientBuilder.build());

        return true;
    }

    /**
     * @param criteresDerniersReglements criteres derniers reglements
     */
    private boolean fillDonneesComplementairesCriteresDerniersReglement(
                    ICriteresDerniersReglements criteresDerniersReglements) {

        boolean isFillOK = false;

        IDonneesComplementaires dtoDonneesComplementaires = criteresDerniersReglements.getDtoDonneesComplementaires();

        if (dtoDonneesComplementaires != null) {

            String typeDestinataireRemboursement = dtoDonneesComplementaires.getTypeDestinataireRemboursement();

            if (StringUtils.isNotBlank(typeDestinataireRemboursement)
                            && TypeDestinataireReglement.containsLibelleClient(typeDestinataireRemboursement)) {

                dtoDonneesComplementaires.setTypeDestinataireRemboursement(TypeDestinataireReglement
                                .getLibelleServiceParLiblleClient(typeDestinataireRemboursement));

                isFillOK = true;
            }
        }

        return isFillOK;

    }

    /**
     * @return mapper builder Informations complementaires
     */
    private Converter<DtoInformationsComplementaires, IInformationsComplementaires> buildMapperInformationComplementaires() {

        Converter<DtoInformationsComplementaires, IInformationsComplementaires> buildMapperInformationComplementaires =
                        new Converter<DtoInformationsComplementaires, IInformationsComplementaires>() {

                            @Override
                            public IInformationsComplementaires convert(DtoInformationsComplementaires source) {
                                IInformationsComplementaires target = new DTOInformationsComplementaires();
                                target.setDateDerniereGeneration(source.getDateDerniereGeneration());
                                return target;
                            }
                        };

        return buildMapperInformationComplementaires;
    }

    /**
     * @return mapper builder personne physique
     */
    private Converter<DtoPersonnePhysique, IPersonnePhysique> buildMapperPersonnePhysique() {

        Converter<DtoPersonnePhysique, IPersonnePhysique> buildMapperPersonnePhysique =
                        new Converter<DtoPersonnePhysique, IPersonnePhysique>() {

                            @Override
                            public IPersonnePhysique convert(DtoPersonnePhysique source) {
                                IPersonnePhysique target = new DTOPersonnePhysique();
                                target.setNom(source.getNom());
                                target.setPrenom(source.getPrenom());

                                return target;
                            }
                        };

        return buildMapperPersonnePhysique;
    }

    /**
     * @return mapper liste reglements sinistres
     */
    private Converter<ArrayOfDtoReglementSinistre, List<IReglementSinistre>> buildMapperListeReglementSinistres() {

        Converter<ArrayOfDtoReglementSinistre, List<IReglementSinistre>> buildMapperReglementSinistres =
                        new Converter<ArrayOfDtoReglementSinistre, List<IReglementSinistre>>() {

                            @Override
                            public List<IReglementSinistre> convert(ArrayOfDtoReglementSinistre source) {

                                List<IReglementSinistre> listeReglementSinistres = null;

                                if (source != null && CollectionUtils.isNotEmpty(source.getDtoReglementSinistres())) {

                                    listeReglementSinistres = new ArrayList<IReglementSinistre>(0);

                                    CollectionUtils.collect(source.getDtoReglementSinistres(),
                                                    buildMapperReglementSinistre(), listeReglementSinistres);
                                }

                                return listeReglementSinistres;
                            }
                        };

        return buildMapperReglementSinistres;
    }

    /**
     * @return mapper builder reglement sinistres
     */
    private Transformer buildMapperReglementSinistre() {

        Transformer buildMapperReglementSinistre = new Transformer() {

            @Override
            public Object transform(Object input) {

                DtoReglementSinistre source = DtoReglementSinistre.class.cast(input);
                IReglementSinistre reglementSinistre = new DTOReglementSinistre();
                reglementSinistre.setDateCreationReglement(source.getDateCreationReglement());
                reglementSinistre.setIdentifiantReglement(source.getIdentifiantReglement());
                reglementSinistre.setMontantReglementBrut(buildMapperQuantity().convert(
                                source.getMontantReglementBrut()));

                return reglementSinistre;
            }
        };

        return buildMapperReglementSinistre;
    }

    /**
     * @return mapper builder reglement quantity
     */
    private Converter<MonetaryQuantity, IQuantity> buildMapperQuantity() {

        Converter<MonetaryQuantity, IQuantity> buildMapperQuantity = new Converter<MonetaryQuantity, IQuantity>() {

            @Override
            public IQuantity convert(MonetaryQuantity source) {

                IQuantity quantity = new DTOQuantity();
                quantity.setUnit(source.getUnit());
                quantity.setValue(source.getValue());

                return quantity;
            }
        };

        return buildMapperQuantity;
    }

    /**
     * @param criteresDerniersReglements criteres derniers reglements
     * @return closure
     */
    private Closure fillTypeDestinataireRegleSinistre(final ICriteresDerniersReglements criteresDerniersReglements) {

        Closure closure = new Closure() {

            @Override
            public void execute(Object input) {

                IReglementSinistre reglementSinistre = IReglementSinistre.class.cast(input);

                IDonneesComplementaires dtoDonneesComplementaires =
                                criteresDerniersReglements.getDtoDonneesComplementaires();

                if (dtoDonneesComplementaires != null) {

                    reglementSinistre.setTypeDestinataireRemboursement(dtoDonneesComplementaires
                                    .getTypeDestinataireRemboursement());

                }
            }
        };

        return closure;
    }

}
